package com.laiyizhan.common.interceptor;

import com.laiyizhan.common.Constants;
import com.laiyizhan.common.exception.VerifySignatureException;
import com.laiyizhan.common.mapper.AppMapper;
import com.laiyizhan.common.utils.SignUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 验签拦截器
 * Created by folie
 */
public class VerifySignatureInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger(VerifySignatureInterceptor.class);

    @Autowired
    private AppMapper appMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse httpServletResponse, Object o) throws Exception {
        Map<String, String> queryMap = new HashMap<>();
        Enumeration parameterNames = request.getParameterNames();

        while (parameterNames.hasMoreElements()) {
            String name = (String) parameterNames.nextElement();
            String value = request.getParameter(name);
            queryMap.put(name, value);
        }
        // 版本
        String v = queryMap.get("v");
        if (!Constants.API_V.equals(v)) {
            throw new VerifySignatureException("非法的版本请求");
        }
        // 获取请求时间
        String timestamp = queryMap.get("timestamp");
        if (StringUtils.isBlank(timestamp)) {
            throw new VerifySignatureException("timestamp 不能为空");
        }
        long now = System.currentTimeMillis();
        long _timestamp = Long.valueOf(timestamp);
        if ((now - _timestamp) > Constants.REQ_TIMEOUT) {
            log.debug("请求时间超过10分钟了");
            throw new VerifySignatureException("请求超时了");
        } else if (_timestamp > now) {
            log.debug("请求时间比服务器时间大, {}", (_timestamp - now));
            if ((_timestamp - now) > Constants.REQ_TIME_5) {
                throw new VerifySignatureException("非法的请求时间");
            }
        }
        // 请求的来源
        String app_id = queryMap.get("app_id");
        if (StringUtils.isBlank(app_id)) {
            throw new VerifySignatureException("app_id 不能为空");
        }
        ServletContext servletContext = request.getSession().getServletContext();
        String app_secret = (String) servletContext.getAttribute(app_id);
        if (app_secret == null) {
            app_secret = appMapper.selectByAppId(Integer.valueOf(app_id));
            if (app_secret == null) {
                throw new VerifySignatureException("非法的 app_id");
            }
            servletContext.setAttribute(app_id, app_secret);
        }
        // 获取签名
        String sign = queryMap.get("sign");
        String _sign = SignUtils.getSign(queryMap, app_secret);
        if (_sign == null || StringUtils.isBlank(sign)) {
            throw new VerifySignatureException("sign 签名不能为空");
        }
        if (!sign.equals(_sign)) {
            throw new VerifySignatureException("验证签名失败");
        }
        // 合法
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
